/*!
 * vinculum
 * Copyright(c) 2017 azzly
 * MIT Licensed
 */
 
'use strict';

/**
 * Module dependencies.
 * @private
 */
const redis = require('redis');

const helper = require("./helper");
const debug = require("./debug")(__filename);

/**
 * Variables
 * @private
 */
 
let _cache = {};

const session_expire_time = 60 * 60 * 24;
const _cache_service_name = 'service_';
const _cache_action_name = 'action_';
const _cache_application_name = 'application_';
const _cache_render_file_name = 'render_file_';
const _cache_render_file_fn_name = 'render_file_fn_';
const _cache_action_lock_name = 'actin_lock_';
const _cache_cookie_pattern_name = 'cookie_pattern_';
const _cache_session_local_name = 'session_cache_local';

/**
 * prototype.
 */

let obj = exports = module.exports = {};

obj.redis_client = null;

/**
 * initRedis
 *
 * @public
 */
 
obj.initRedis = function(redisOptions,callback){
	obj.redis_client = redis.createClient(redisOptions);
	obj.redis_client.on("error", (err)=> {
		debug("cache redis client error:  ",err);
		if(callback) callback();
	});
	obj.redis_client.on("ready", (err)=> {
		debug("redis ready");
		if(callback) callback();
	});
};

/**
 * get
 *
 * @public
 */
 
obj.get = function(name){
	if(name) return _cache[name];
	else return null;
};

/**
 * set
 *
 * @public
 */
 
obj.set = function(name,value){
	if(name) _cache[name] = value;
};

/**
 * getSession
 *
 * @public
 */
 
obj.getSession = function(name){
	const key_name = _cache_session_local_name + name;
	return new Promise((resolve, reject)=>{
		if(obj.redis_client){
			obj.redis_client.get(key_name, function (err, reply) {
				if(reply){
					reply = helper.string2json(reply);
				}
				resolve(reply || {createtime:Date.now()});
			});
		}else{
			let sessionData = obj.get(key_name);
			if(!sessionData || ((Date.now() - sessionData.createtime)>session_expire_time * 1000)){
				debug('session expired!');
				sessionData = {};
			}
			sessionData.createtime = Date.now();
			resolve(sessionData);
		}
	});
};

/**
 * setSession
 *
 * @public
 */
 
obj.setSession = function(name,value){
	let key_name = _cache_session_local_name + name;
	return new Promise((resolve, reject)=>{
		if(obj.redis_client){
			if(value){
				value = helper.json2string(value);
			}else{
				value = "";
			}
			obj.redis_client.set(key_name,value ,(err, replies)=> {
				if(err){
					debug(err);
				}
				obj.redis_client.expire(key_name,session_expire_time);
				resolve();
			});
			
		}else{
			obj.set(key_name,value);
			resolve();
		}
	});
};

/**
 * getCookiePattern
 *
 * @public
 */
 
obj.getCookiePattern = function(name){
  return obj.get(_cache_cookie_pattern_name + name);
};

/**
 * setCookiePattern
 *
 * @public
 */
 
obj.setCookiePattern = function(name,value){
	obj.set(_cache_cookie_pattern_name + name,value);
};

/**
 * getActionLocked
 *
 * @public
 */
 
obj.getActionLocked = function(name){
	return obj.get(_cache_action_lock_name + name);
};

/**
 * setActionLocked
 *
 * @public
 */
 
obj.setActionLocked = function(name,value){
	obj.set(_cache_action_lock_name + name,value);
};

/**
 * getRenderFile
 *
 * @public
 */
 
obj.getRenderFile = function(name){
	return obj.get(_cache_render_file_name + name);
};

/**
 * setRenderFile
 *
 * @public
 */
 
obj.setRenderFile = function(name,value){
	obj.set(_cache_render_file_name + name,value);
};

/**
 * getRenderFileFn
 *
 * @public
 */
 
obj.getRenderFileFn = function(name){
	return obj.get(_cache_render_file_fn_name + name);
};

/**
 * setRenderFileFn
 *
 * @public
 */
 
obj.setRenderFileFn = function(name,value){
	obj.set(_cache_render_file_fn_name + name,value);
};

/**
 * getApplication
 *
 * @public
 */
 
obj.getApplication = function(name){
	return obj.get(_cache_application_name + name);
};

/**
 * setApplication
 *
 * @public
 */
 
obj.setApplication = function(name,value){
	obj.set(_cache_application_name + name,value);
};

/**
 * getAction
 *
 * @public
 */
 
obj.getAction = function(name){
	return obj.get(_cache_action_name + name);
};

/**
 * setAction
 *
 * @public
 */
 
obj.setAction = function(name,value){
	obj.set(_cache_action_name + name,value);
};

/**
 * getService
 *
 * @public
 */
 
obj.getService = function(name){
	return obj.get(_cache_service_name + name);
};

/**
 * setService
 *
 * @public
 */
 
obj.setService = function(name,value){
	obj.set(_cache_service_name + name,value);
};

/**
 * clear
 *
 * @public
 */
 
obj.clear = function(){
	_cache = {};
};